package week01.classloader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

public class ByteCodeLoader extends ClassLoader {

    private byte[] readClass(String byteCodePath) throws IOException {
        try (InputStream in = ByteCodeLoader.class.getResourceAsStream(byteCodePath)) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int read = in.read(buffer);
            while (read > 0) {
                for (int i=0; i < read; i++) {
                    buffer[i] = (byte) (255 - buffer[i]);
                }
                out.write(buffer, 0, read);
                read = in.read(buffer);
            }
            return out.toByteArray();
        }
    }

    public void defineCustomClass(String fullClassName, String byteCodePath) throws IOException {
        byte[] bc = readClass(byteCodePath);
        defineClass(fullClassName, bc, 0, bc.length);
    }

    public static void main(String[] args) throws Exception {
        String fullClassName = "Hello";
        String byteCodePath = "/Hello.xlass";

        ByteCodeLoader loader = new ByteCodeLoader();
        loader.defineCustomClass(fullClassName, byteCodePath);
        Class<?> c = loader.loadClass(fullClassName);
        Method m = c.getMethod("hello");
        m.invoke(c.getConstructor().newInstance());
    }
}
